<template>
	<view
		@tap="backToTop"
		class="u-back-top"
		:class="['u-back-top--mode--' + mode]"
		:style="[{
			bottom: bottom + 'rpx',
			right: right + 'rpx',
			borderRadius: mode == 'circle' ? '10000rpx' : '8rpx',
			zIndex: uZIndex,
			opacity: opacity
		}, customStyle]"
	>
		<view
			class="u-back-top__content"
			v-if="!$slots.default && !$slots.$default"
		>
			<u-icon
				@click="backToTop"
				:name="icon"
				:custom-style="iconStyle"
			/>
			<view class="u-back-top__content__tips">
				{{tips}}
			</view>
		</view>
		<slot v-else />
	</view>
</template>

<script>
export default {
  name: 'u-back-top',
  props: {
    // 返回顶部的形状，circle-圆形，square-方形
    mode: {
      type: String,
      default: 'circle'
    },
    // 自定义图标
    icon: {
      type: String,
      default: 'arrow-upward'
    },
    // 提示文字
    tips: {
      type: String,
      default: ''
    },
    // 返回顶部滚动时间
    duration: {
      type: [Number, String],
      default: 100
    },
    // 滚动距离
    scrollTop: {
      type: [Number, String],
      default: 0
    },
    // 距离顶部多少距离显示，单位rpx
    top: {
      type: [Number, String],
      default: 400
    },
    // 返回顶部按钮到底部的距离，单位rpx
    bottom: {
      type: [Number, String],
      default: 200
    },
    // 返回顶部按钮到右边的距离，单位rpx
    right: {
      type: [Number, String],
      default: 40
    },
    // 层级
    zIndex: {
      type: [Number, String],
      default: '9'
    },
    // 图标的样式，对象形式
    iconStyle: {
      type: Object,
      default() {
        return {
          color: '#909399',
          fontSize: '38rpx'
        }
      }
    },
    // 整个组件的样式
    customStyle: {
      type: Object,
      default() {
        return {}
      }
    }
  },
  watch: {
    showBackTop(nVal, oVal) {
      // 当组件的显示与隐藏状态发生跳变时，修改组件的层级和不透明度
      // 让组件有显示和消失的动画效果，如果用v-if控制组件状态，将无设置动画效果
      if (nVal) {
        this.uZIndex = this.zIndex
        this.opacity = 1
      } else {
        this.uZIndex = -1
        this.opacity = 0
      }
    }
  },
  computed: {
    showBackTop() {
      // 由于scrollTop为页面的滚动距离，默认为px单位，这里将用于传入的top(rpx)值
      // 转为px用于比较，如果滚动条到顶的距离大于设定的距离，就显示返回顶部的按钮
      return this.scrollTop > uni.upx2px(this.top)
    },
  },
  data() {
    return {
      // 不透明度，为了让组件有一个显示和隐藏的过渡动画
      opacity: 0,
      // 组件的z-index值，隐藏时设置为-1，就会看不到
      uZIndex: -1
    }
  },
  methods: {
    backToTop() {
      uni.pageScrollTo({
        scrollTop: 0,
        duration: this.duration
      })
    }
  }
}
</script>

<style lang="scss" scoped>
	@import "../../libs/css/style.components.scss";

	.u-back-top {
		width: 80rpx;
		height: 80rpx;
		position: fixed;
		z-index: 9;
		@include vue-flex;
		flex-direction: column;
		justify-content: center;
		background-color: #E1E1E1;
		color: $u-content-color;
		align-items: center;
		transition: opacity 0.4s;

		&__content {
			@include vue-flex;
			flex-direction: column;
			align-items: center;

			&__tips {
				font-size: 24rpx;
				transform: scale(0.8);
				line-height: 1;
			}
		}
	}
</style>
